source: here
In [2]:
import numpy
In [5]:
def error(P, Q, i, j):
return R[i][j] - numpy.dot(P[i,:],Q[:,j])
def regular(beta, P, Q, i, k, j):
return (beta/2) * (pow(P[i][k], 2) + pow(Q[k][j], 2))
def matrix_factorization(R, P, Q, K, steps=5000, alpha=0.0002, beta=0.02):
Q = Q.T
for step in range(steps):
for i in range(len(R)):
for j in range(len(R[i])):
if R[i][j] > 0:
for k in range(K):
P[i][k] = P[i][k] + alpha * (2 * error(P, Q, i, j)
* Q[k][j] - beta * P[i][k])
Q[k][j] = Q[k][j] + alpha * (2 * error(P, Q, i, j)
* P[i][k] - beta * Q[k][j])
eR = numpy.dot(P,Q)
e = 0
for i in range(len(R)):
for j in range(len(R[i])):
if R[i][j] > 0:
e = e + error(P, Q, i, j) ** 2
for k in range(K):
e = e + regular(beta, P, Q, i, k, j)
if e < 0.001:
break
return P, Q.T
In [6]:
R = [
[5,3,0,1],
[4,0,0,1],
[1,1,0,5],
[1,0,0,4],
[0,1,5,4],
]
R = numpy.array(R)
N = len(R)
M = len(R[0])
# number of dimension about factor vector
K = 2
P = numpy.random.rand(N,K)
Q = numpy.random.rand(M,K)
nP, nQ = matrix_factorization(R, P, Q, K)
nR = numpy.dot(nP, nQ.T)
print(nR)